/*
 * Copyright (C) Michael Martin & Antonio Carrozzini (TBJD)
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */

package org.tbjd.client.guis;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.tbjd.client.borderDetectors.GanttBorderNotifier;
import org.tbjd.client.builders.GanttBuilder;
import org.tbjd.client.builders.ResourcePickerBuilder;
import org.tbjd.client.builders.TaskListBuilder;
import org.tbjd.client.constants.GanttConstants;
import org.tbjd.client.dndControllers.resourcePicker.ResourcePickerDragController;
import org.tbjd.client.guis.gantt.GanttGui;
import org.tbjd.client.guis.resourcePicker.ResourcePickerGui;
import org.tbjd.client.guis.taskList.TaskListGui;
import org.tbjd.client.interfaces.BorderTrigger;
import org.tbjd.client.interfaces.Builder;
import org.tbjd.client.interfaces.Displayer;
import org.tbjd.client.interfaces.Observer;
import org.tbjd.client.mediators.AbstractMediator;
import org.tbjd.client.mediators.GanttMediator;
import org.tbjd.client.mediators.ResourcePickerMediator;
import org.tbjd.client.mediators.TaskListMediator;

import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.WindowResizeListener;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.DockPanel;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.ScrollListener;
import com.google.gwt.user.client.ui.ScrollPanel;
import com.google.gwt.user.client.ui.Widget;

/**
 * <p>
 * The application layout consisting of 4 zones :
 * <li>NORTH : menu of the application</li>
 * <li>WEST : list {@link org.tbjd.client.beans.Task Tasks} (TasksList)</li>
 * <li>CENTER : displays infos depending user action (i.e. {@link org.tbjd.client.guis.gantt.GanttGui GanttGui}, AssignView...)</li>
 * <li>EAST : list of {@link org.tbjd.client.beans.Resource Resources} ({@link org.tbjd.client.guis.resourcePicker.ResourcePickerGui ResourcePickerGui})</li>
 * </p>
 * 
 * @author Michael Martin
 * @author Antonio Carrozzini
 * @version 1.0
 * 
 */
public class ApplicationLayoutGui extends Composite implements WindowResizeListener, Builder, Observer, Displayer, BorderTrigger {

	private AbstractMediator chiefMediator = null;
	private DockPanel container = null;
	private HorizontalPanel menuContainer;
	private ResourcePickerGui resourcePickerGui;
	private GanttGui ganttGui;
	private ScrollPanel scrollPanel = null;
	private GanttBorderNotifier borderNotifier = null;

	Map<Integer, Object> map = new HashMap<Integer, Object>();
	private TaskListGui tasksListGui;
	private ResourcePickerDragController resourcePickerDragController;

	/**
	 * Constructs the ApplicationLayoutGui
	 * 
	 * @param mediator
	 *            the top mediator ({@link org.tbjd.client.mediators.ChiefMediator ChiefMediator})
	 */
	public ApplicationLayoutGui(AbstractMediator mediator) {
		this.chiefMediator = mediator;
		this.chiefMediator.addObserver(this);
		build();
		initWidget(this.container);
		display();
		defineTrigger();
		addBorderNotifier();
	}

	public void build() {
		Window.addWindowResizeListener(this);

		this.container = new DockPanel();
		this.container.setBorderWidth(1);
		this.container.setStyleName("tbjd_applicationLayout");

		buildMenuContainer();
		buildTasksList();
		buildGantt();
		buildResourcePicker();
	}

	private void buildMenuContainer() {
		this.menuContainer = new HorizontalPanel();
		this.menuContainer.setStyleName("tbjd_applicationLayout_menuContainer");
		this.menuContainer.add(new Button("Switch"));

		this.container.add(this.menuContainer, DockPanel.NORTH);
		this.container.setCellHeight(this.menuContainer, "30px");
	}

	private void buildTasksList() {
		TaskListMediator taskListMediator = new TaskListMediator();
		taskListMediator.setMediator(this.chiefMediator);

		TaskListBuilder taskListBuilder = new TaskListBuilder();
		taskListBuilder.setMediator(taskListMediator);
		
		this.tasksListGui = (TaskListGui) taskListBuilder.getBuildedWidget();
	}

	private void buildResourcePicker() {
		ResourcePickerMediator resourcePickerMediator = new ResourcePickerMediator();
		resourcePickerMediator.setMediator(this.chiefMediator);

		ResourcePickerBuilder resourcePickerBuilder = new ResourcePickerBuilder();
		resourcePickerBuilder.setMediator(resourcePickerMediator);
		resourcePickerBuilder.setDragController(this.resourcePickerDragController);

		this.resourcePickerGui = (ResourcePickerGui) resourcePickerBuilder.getBuildedWidget();
	}

	private void buildGantt() {
		GanttMediator ganttMediator = new GanttMediator();
		ganttMediator.setMediator(this.chiefMediator);

		GanttBuilder ganttBuilder = new GanttBuilder();
		this.resourcePickerDragController = new ResourcePickerDragController(((GanttGui) ganttBuilder.getBuildedWidget()).getContainer(), false);
		ganttBuilder.setMediator(ganttMediator);
		ganttBuilder.setDragController(this.resourcePickerDragController);

		this.ganttGui = (GanttGui) ganttBuilder.getBuildedWidget();

	}

	private void setWestPanel(Widget panel) {
		this.container.add(panel, DockPanel.WEST);
	}

	private void setCenterPanel(Widget panel) {
		this.scrollPanel = new ScrollPanel(panel);
		this.scrollPanel.addScrollListener(new ScrollListener() {
			public void onScroll(Widget widget, int scrollLeft, int scrollTop) {
				GanttConstants.SCROLL_HORIZONTAL_OFFSET = scrollLeft;
			}
		});
		;
		this.container.add(this.scrollPanel, DockPanel.CENTER);
		// FIXME vertical scrollbar doesn't fit the timeline height
		this.scrollPanel.setSize(Window.getClientWidth() - 420 + "px", Window.getClientHeight() - 50 + "px");
	}

	private void setEastPanel(Widget panel) {
		this.container.add(panel, DockPanel.EAST);
	}

	public void onWindowResized(int width, int height) {
		this.scrollPanel.setSize(width - 420 + "px", Window.getClientHeight() - 23 + "px");
	}

	public void display() {
		setWestPanel(this.tasksListGui);
		setEastPanel(this.resourcePickerGui);
		setCenterPanel(this.ganttGui);
	}

	public Widget getBuildedWidget() {
		return this.container;
	}

	public void addBorderNotifier() {
		this.borderNotifier = GanttBorderNotifier.getInstance();
		this.borderNotifier.setInterval(50);
	}

	public void defineTrigger() {
		//sinkEvents(Event.ONMOUSEMOVE);
		//sinkEvents(Event.ONMOUSEOUT);
	}

	public void onBrowserEvent(Event event) {
		super.onBrowserEvent(event);

		switch (event.getTypeInt()) {
		case Event.ONMOUSEMOVE:
			this.borderNotifier.mouseEvent(this.scrollPanel, null, (GanttConstants.SCROLL_HORIZONTAL_OFFSET + event.getClientX()),
					GanttConstants.SCROLL_HORIZONTAL_OFFSET + event.getClientY());
			break;

		case Event.ONMOUSEOUT:
			this.borderNotifier.cancel();
			break;
		}

	}

	public void update(Object sender) {
		System.out.println("ApplicationLayoutGui.update()");
	}

	public void display(List<?> updatedBeans) {
		
	}

}
